'use strict'

const http=require('http');
const fs=require('fs');

//! 解析body数据中的消息头
function parseBodyHeaders(data){
    let headers={}
                                //? 筛选出满足条件的数组元素 
    let dsplit=data.split('\r\n').filter(p => p.length > 0)

    let ind
    let k
    for(let d of dsplit){
        ind = d.indexOf(':')
        if(ind<=0) continue
        k=d.substring(0,ind).toLowerCase()
                                    //? 去除字符串的头尾空格
        headers[k]=d.substring(ind+1).trim()
    }
    let cpd=headers['content-disposition']
    //按照; 分割成数组，第一个元素form-data去掉
    let clist=cpd.split('; ').slice(1)

    let name,filename
    for(let a of clist){
        ind=a.indexOf('filename="');
        if(ind>=0){
            filename=a.substring(ind+10,a.length-1)
        }else{
            name=a.substring(6,a.length-1)
        }
    }
    return{
        headers,
        name,
        filename
    }
    
}


/**
 * 
 * @param {Buffer} bodyData 原始的Body数据
 * @param {Object} reqHeaders request.headers
 */

//! 解析body数据
function parseBody(bodyData,reqHeaders){

    // content-type格式如下
    //content-type:multipart/form-data; boundary=----342694329
    let ctype=reqHeaders['content-type']
    // 通过偏移量拿到字符串 拿到分界线boundary
    let bdy=ctype.substring(ctype.indexOf('=')+1)
    // 数据中用于分割文件的分界线
    // bdy='--${bdy}\r\n'
    
    //? 结尾分界线
    let crlf_body=`\r\n--${bdy}`

    // 从偏移body的长度开始查找下一个分界线的位置
    let data_end_index=bodyData.indexOf(crlf_body,crlf_body.length);
    // body消息数据中的header部分的最后索引
    let header_end_index=bodyData.indexOf('\r\n\r\n',crlf_body.length);
                                            // 开始索引值，结束位置
    let header_data=bodyData.toString('utf8',crlf_body.length,header_end_index);

    // 解析body数据中的消息头
    let hd=parseBodyHeaders(header_data)

    let fileinfo={
                            // /r/n/r/n 
        start:header_end_index+4,
        end:data_end_index,
    }
    fileinfo.length=fileinfo.end-fileinfo.start
    return{
        name:hd.name,
        filename:hd.filename,
        headers:hd.headers,
        start:fileinfo.start,
        end:fileinfo.end,
        length:fileinfo.length
    }
}

//! 和second-http原理一样 
let routerTable={
    GET:{
        '/upload':async(request,response)=>{
            let stm=fs.createReadStream('./upload.html');
            stm.pipe(response);
            stm.on('end',()=>{
                response.end()
            })
        }
    },
    POST:{
        '/upload':async(request,response)=>{

            console.log(request.headers['content-type'])

            let bufferList=[];
            let totalLength=0;
            request.on('data',chunk=>{
                totalLength+=chunk.length;
                bufferList.push(chunk);

                let bodyData=null

                request.on('end',()=>{
                    bodyData=Buffer.concat(bufferList,totalLength)
                    bufferList=[];

                    // 解析Body数据
                    let body =parseBody(bodyData,request.headers);
                    console.log(body)

                    response.setHeader('content-type','text/plain; charest=utf-8');
                    response.end(bodyData);
                })
            })
        }
    }
}


let serv=http.createServer()
serv.on('request',(request,response)=>{
    // request.method:get 或者是 post
    let rm=routerTable[request.method];
    if(!rm || !rm[request.url]){
        response.statusCode=404;
        response.end('page not found')
        return
    }
    rm[request.url](request,response)
})
serv.listen(3456)